﻿/*
 * 词法分析程序.
 * data.txt 存放装提啊转换矩阵.
 * source.c 存放经过预处理后的程序.除了末尾,不含有注释,回车换行.
 *  
 * 杨晓辰
 * 2011-03-26 
 *
 */


#include <stdio.h>
#define C_NUM 50
#define S_NUM 100

int m[S_NUM][C_NUM]; // 存放关系转换矩阵 
int f[S_NUM];       // 终态集合数组 
char charset[C_NUM]; // 字符集合数组 
int s_num=0,f_num=0,c_num=0;


// findState()函数通过一个前驱状态和一个接收字符,返回后继状态. 
int findState(int state,char ch){
    int i;
    int flag=0;
    
    if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')){ // 将所有字母用'a'代替.所以状态转换矩阵中用'a'表示所有字母. 
        ch='a';
    }else if(ch>='0' && ch<='9'){   // 将所有数字用'0'代替.含义同上. 
        ch='0';    
    }
      
    for(i=0;i<c_num;i++){
        if(ch==charset[i]){
            return m[state][i]; // 返回后继状态 
        }
    }    
    return -1; // 状态转换矩阵中未找到相对应字符,返回-1.    
}


// isFinal()函数来判断一个状态是否为终态.是返回1,不是返回0; 
int isFinal(int state){
    int i;
    for(i=0;i<f_num;i++){
        if(state==f[i]){
            return 1;
        }    
    }
    return 0;
}


// loadData()函数载入data.txt中的数据.包含状态转换矩阵. 
void loadData(FILE *fp){
    int i,j;
    if((fp=fopen("data.txt","r"))==NULL){
        printf("File data.txt is not exsit!\n");
        system("pause"); 
        exit(0);
    }else {
        printf("Open file successfully!\n");
    }
       
    fscanf(fp,"%d%d%d",&s_num,&f_num,&c_num);// 读入 状态总数,终态数,字符数 

    for(i=0;i<f_num;i++){ // 读入所有终态 
        fscanf(fp,"%d",&f[i]);
    }
    
    fgetc(fp); // 吃掉回车 
    
    for(i=0;i<c_num;i++){ // 读入所有字符. 
        fscanf(fp,"%c",&charset[i]);
    }
    
    for(i=0;i<s_num;i++){ // 读入状态转换矩阵. 
        for(j=0;j<c_num;j++){
            fscanf(fp,"%d",&m[i][j]);
        }
    }
    fclose(fp);
} 




int main(){
    FILE *fp,*fp1,*fp2;
    int i,j;
    int state;
    char ch;
      
    loadData(fp);
    
       
    if((fp1=fopen("source.c","r"))==NULL){
        printf("File source.c is not exsit!\n");
        system("pause"); 
        exit(0);
    }else {
        printf("Open file successfully!\n");
    }
    
    while((ch=fgetc(fp1))!=EOF && ch!='\n'){ //读到文件结尾或者遇到'\n'结束. 
        fseek(fp1,-1,1);
        state = 0;
        while(!isFinal(state)){          // 如果不是终态,读取下一个字符急需熏着终态. 
            if((ch=fgetc(fp1))!=EOF){
                state = findState(state,ch);
                if(state==-1){
                    printf("Error:Do not have this character!\n");
                    system("pause"); 
                    exit(0);
                }
            }
            
        }
        
        if(!feof(fp1)){ // 回退一个字节. 原因见说明. 
            fseek(fp1,-1,1);          
        }
        printf("state=%d\n",state); // 打印状态. 
             
    }
     

    fclose(fp1);
    system("pause");    
}
